package org.wxl.utils;

import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT 工具类（Spring Bean 单例模式）
 */
@Slf4j
@Component
public class JWTUtils {
    // 从配置文件注入参数（示例：application.properties）
    @Value("${jwt.secret}")
    private String secret; // 推荐长度32字符以上的密钥

    @Value("${jwt.expiration}")
    private Long expiration; // 过期时间（毫秒）

    // HMAC-SHA256 密钥生成
    public SecretKey generateKey() {
        byte[] keyBytes = secret.getBytes(StandardCharsets.UTF_8);
        return new SecretKeySpec(keyBytes, "HmacSHA256");
    }

    /**
     * 生成JWT令牌
     * @param userDetails 用户信息
     * @return 令牌字符串
     */
    public String generateToken(UserDetails userDetails) {
        Map<String, Object> claims = new HashMap<>();
        // 添加自定义声明（可根据需要扩展）
        claims.put("authorities", userDetails.getAuthorities());

        return Jwts.builder()
                .setClaims(claims)
                .setSubject(userDetails.getUsername()) // 唯一标识
                .setIssuer("your_issuer")              // 签发者
                .setIssuedAt(new Date())              // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .signWith(generateKey(), SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * 解析令牌
     */
    public Claims parseToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(generateKey())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 从令牌中提取用户名
     */
    public String extractUsername(String token) {
        return parseToken(token).getSubject();
    }

    /**
     * 验证令牌有效性
     */
    public boolean validateToken(String token, UserDetails userDetails) {
        try {
            final String username = extractUsername(token);
            return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
        } catch (JwtException | IllegalArgumentException e) {
            log.warn("JWT验证失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 检查令牌是否过期
     */
    private boolean isTokenExpired(String token) {
        Date expirationDate = parseToken(token).getExpiration();
        return expirationDate.before(new Date());
    }

    // 异常细化处理（供外部调用）
    public boolean isTokenInvalid(String token) {
        try {
            parseToken(token);
            return false;
        } catch (ExpiredJwtException ex) {
            log.warn("Token已过期: {}", ex.getMessage());
            return true;
        } catch (UnsupportedJwtException ex) {
            log.warn("不支持的Token格式: {}", ex.getMessage());
            return true;
        } catch (MalformedJwtException ex) {
            log.warn("Token结构损坏: {}", ex.getMessage());
            return true;
        } catch (SignatureException ex) {
            log.warn("签名验证失败: {}", ex.getMessage());
            return true;
        } catch (IllegalArgumentException ex) {
            log.warn("非法参数: {}", ex.getMessage());
            return true;
        }
    }
}
//package org.wxl.utils;
//
//import io.jsonwebtoken.Claims;
//import io.jsonwebtoken.JwtBuilder;
//import io.jsonwebtoken.Jwts;
//import io.jsonwebtoken.SignatureAlgorithm;
//import org.springframework.security.core.userdetails.UserDetails;
//import org.springframework.stereotype.Component;
//
//import javax.crypto.SecretKey;
//import javax.crypto.spec.SecretKeySpec;
//import java.nio.charset.StandardCharsets;
//import java.util.Base64;
//import java.util.Date;
//import java.util.UUID;
//
////jwt工具类
//@Component
//public class JWTUtils {
//    //有效期
//    public static final Long JWT_TTL = 60*60*1000L;//60 * 60 *1000  一个小时
//    // 使用安全的密钥长度（至少256位）
//    public static final String JWT_KEY = "WXLjiayou1_WXLjiayou1_WXLjiayou1_123"; // 32字符以上
//
//    //生成为每一个jwt生成一个特定的uuid的令牌
//    public static String getUUID(){
//        return UUID.randomUUID().toString().replaceAll("-","");
//    }
//    /**
//     * 生成jwt令牌
//     * @param subject  playload中要存放的数据（json格式）存放用户id，角色，权限等数据
//     * @param ttlMillis 有效时间
//     * @return
//     */
//    public static String createJWT(String subject,Long ttlMillis)
//    {
//        JwtBuilder builder=getJwtBuilder(subject,ttlMillis,getUUID());
//        return builder.compact();
//    }
//
//    /**
//     * 使用指定id生成token
//     */
//
//    public static String createJWT(String id ,String subject,long l)
//    {
//        JwtBuilder jwtBuilder=getJwtBuilder(subject,l,id);
//        return jwtBuilder.compact();
//    }
//
//    /**
//     * 生成jwt令牌业务逻辑
//     */
//    private static JwtBuilder  getJwtBuilder(String subject,Long ttlMillis,String id)
//    {
//        //创建jwtBuilder
//        SignatureAlgorithm signatureAlgorithm=SignatureAlgorithm.HS256;
//        SecretKey secretKey= generaKey();
//
//        long nowMillis=System.currentTimeMillis();
//        Date now = new Date(nowMillis);
//        if(ttlMillis==null)
//        {
//            ttlMillis=JWTUtils.JWT_TTL;
//        }
//        long expMillis=nowMillis+ttlMillis;
//        Date expDate=new Date(expMillis);
//        return Jwts.builder()
//                .setId(id)
//                .setSubject(subject)
//                .setIssuer("wxl")
//                .setIssuedAt(now)
//                .signWith(signatureAlgorithm,secretKey)
//                .setExpiration(expDate);
//
//    }
//
//    // 正确的HMAC-SHA256密钥生成
//    private static SecretKey generaKey() {
//        // 直接取UTF-8字节
//        byte[] keyBytes = JWT_KEY.getBytes(StandardCharsets.UTF_8);
//        return new SecretKeySpec(keyBytes, "HmacSHA256");
//    }
//    /**
//     * 解析token
//     */
//    public static Claims parseJWT(String jwt)
//    {
//        SecretKey secretKey=generaKey();
//        return Jwts.parser()
//                .setSigningKey(secretKey)
//                .parseClaimsJws(jwt)
//                .getBody();
//    }
//
//
//    /**
//     * 解析token获取用户名
//     * @param token
//     * @return
//     */
//    public String extractUsername(String token) {
//        return Jwts.parser()
//                //  使用统一密钥生成方法
//                .setSigningKey(generaKey())
//                .parseClaimsJws(token)
//                .getBody()
//                .getSubject();
//    }
//
//    /**
//     * 验证token是否有效
//     */
//    public boolean validateToken(String token , UserDetails userDetails){
//        final String username = extractUsername(token);
//        return (username.equals(userDetails.getUsername())) && !isTokenExpired(token);
//    }
//
//    /**
//     * 判断token是否失效
//     */
//    public boolean isTokenExpired(String token) {
//        Date expireDate = Jwts.parser()
//                // 使用统一密钥生成方法
//                .setSigningKey(generaKey())
//                .parseClaimsJws(token)
//                .getBody()
//                .getExpiration();
//        return expireDate.before(new Date());
//    }
//
//}
